package user

import (
	"easy-sys/base/entity"
	"easy-sys/server/middleware/easyjwt"
	"easy-sys/sys/domain/menu"
	"easy-sys/sys/domain/role"
	"easy-sys/sys/domain/user"
	"easy-sys/utils"
	"easy-sys/utils/pbkdf2"
	"encoding/json"
	"net/http"
	"strings"
	"time"

	"github.com/gin-contrib/sessions"

	jwtgo "github.com/dgrijalva/jwt-go"

	"github.com/gin-gonic/gin"
)

// Delete 删除用户
func Delete(c *gin.Context) {
	var sysUser user.SysUser
	c.ShouldBind(&sysUser)
	var updateCount = user.Delete(sysUser)
	if updateCount == 1 {
		c.JSON(http.StatusOK, utils.GetSuccessMessage("删除成功"))
	} else {
		c.JSON(http.StatusOK, utils.GetFailureMessage("删除失败"))
	}
}

// Save 新建或者修改用户
func Save(c *gin.Context) {
	var sysUser user.SysUser
	c.ShouldBind(&sysUser)
	if sysUser.UserPwd != "" {
		sysUser.UserSalt = pbkdf2.CreateRandomString(32)                               // 生成随机盐值
		sysUser.UserPwd = pbkdf2.EncryptPwdWithSalt(sysUser.UserPwd, sysUser.UserSalt) // 加密密码
	}
	if sysUser.UserId == 0 {
		sysUser.CreateTime = entity.JSONTime(time.Now())
		sysUser.CreateBy = c.MustGet("userId").(uint64)
	}
	// 无论创建还是修改都是需要更新修改时间和修改人的
	sysUser.UpdateTime = entity.JSONTime(time.Now())
	sysUser.UpdateBy = c.MustGet("userId").(uint64)
	var updateCount = user.Save(sysUser)
	if updateCount == 1 {
		c.JSON(http.StatusOK, utils.GetSuccessMessage("保存成功"))
	} else {
		c.JSON(http.StatusOK, utils.GetFailureMessage("保存失败"))
	}
}

// List 获取分页用户
func List(c *gin.Context) {
	var sysUser user.SysUser
	var pageVO entity.EasyPage
	c.ShouldBindQuery(&pageVO)
	c.ShouldBind(&sysUser)

	pageVO = user.List(sysUser, pageVO)

	c.JSON(http.StatusOK, utils.GetSuccessMessage(pageVO))
}

// Logout 退出登录，直接返回，因为不能控制不使用token
func Logout(c *gin.Context) {
	c.JSON(http.StatusOK, utils.GetSuccessMessage("退出成功"))
}

// Login 登录
func Login(c *gin.Context) {
	var userLogin user.SysUserLogin
	c.ShouldBind(&userLogin)
	if userLogin.Username != "" && userLogin.Password != "" {
		var u = user.SysUser{}
		u.UserName = userLogin.Username
		u = user.FindOneByUser(u)

		var enCodePwd = pbkdf2.EncryptPwdWithSalt(userLogin.Password, u.UserSalt)
		if strings.Compare(enCodePwd, u.UserPwd) == 0 {
			saveSession(c, u)
			generateToken(c, u)
		} else {
			c.JSON(http.StatusOK, utils.GetFailureMessage("用户名密码错误"))
		}
	} else {
		c.JSON(http.StatusOK, utils.GetFailureMessage("请输入用户名和密码"))
	}
}

// GetUserByRole 获取角色拥有的用户
func GetUserByRole(c *gin.Context) {
	var sysRole = role.SysRole{}
	c.ShouldBind(&sysRole)

	var pageVO entity.EasyPage
	c.ShouldBind(&pageVO)

	var sysUser user.SysUser
	c.ShouldBind(&sysUser)

	pageVO = user.GetUserByRoleId(sysUser, sysRole.RoleId, pageVO)

	c.JSON(http.StatusOK, utils.GetSuccessMessage(pageVO))
}

// Info 获取用户信息
func Info(c *gin.Context) {
	c.JSON(http.StatusOK, utils.GetSuccessMessage(c.MustGet("userInfo").(*user.SysUser)))
}

func saveSession(c *gin.Context, u user.SysUser) {
	session := sessions.Default(c)
	var sessionUser = user.SysUser{}
	sessionUser.Name = u.UserName
	sessionUser.Avatar = "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"
	sessionUser.MenuList = menu.GetUserMenu(u.UserId)
	sessionUser.Permissions = menu.GetUserPermission(u.UserId)
	data, _ := json.Marshal(sessionUser)
	session.Set("userInfo", string(data)) // session 使用string存储
	session.Save()
}

// 生成令牌
func generateToken(c *gin.Context, u user.SysUser) {
	claims := easyjwt.CustomClaims{
		UserId:      u.UserId,
		UserName:    u.UserName,
		UserAccount: "", // 数据库没有这个字段
		StandardClaims: jwtgo.StandardClaims{
			NotBefore: int64(time.Now().Unix() - 1000), // 签名生效时间
			ExpiresAt: int64(time.Now().Unix() + 3600), // 过期时间 一小时
			Issuer:    "fantasy",                       //签名的发行者
		},
	}

	token, err := easyjwt.CreateToken(claims)

	if err != nil {
		c.JSON(http.StatusOK, utils.GetFailureMessage("生成Token错误："+err.Error()))
		return
	}

	c.JSON(http.StatusOK, utils.GetSuccessMessage(gin.H{
		"token": token,
	}))
	return
}
